package com.sxkiler.demo.utils;

import com.alibaba.druid.filter.config.ConfigTools;
import com.sxkiler.demo.biz.dao.BaseDao;
import org.apache.ibatis.binding.MapperProxyFactory;
import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;

import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * 数据源管理类
 */
public class DaoContext {
    private static Logger logger = LoggerFactory.getLogger(DaoContext.class);

    /**
     * 懒加载,single
     */
    private DaoContext(){}
    private static DaoContext context;
    public static DaoContext getInstance(){
        if(context==null){
            context = new DaoContext();
        }
        return context;
    }

    //dao缓存
    private Map<String, BaseDao> daoMap = new HashMap<String,BaseDao>();
    private SqlSessionFactory factory;
    private String mapperPaths;
    public DataSource initDataSource(String url,String username,String password)throws Exception{
        Map<String, Object> dataSourceProperties = new HashMap();
        dataSourceProperties.put("driverClassName","com.mysql.cj.jdbc.Driver");
        dataSourceProperties.put("url",url);
        dataSourceProperties.put("username",username);
        dataSourceProperties.put("password",password);
        dataSourceProperties.put("max-active",10);
        dataSourceProperties.put("initialSize",2);
        DataSource result = (DataSource) Class.forName("com.alibaba.druid.pool.DruidDataSource").newInstance();
        for (Map.Entry<String, Object> entry : dataSourceProperties.entrySet()) {
            BeanUtils.callSetterMethod(result, BeanUtils.getSetterMethodName(entry.getKey()), null == entry.getValue() ? null : entry.getValue().toString());
        }
        return result;
    }

    public void initMybatis(DataSource dataSource)throws Exception{
        long starttime = System.currentTimeMillis();
        Properties configurationProperties = new Properties();
        configurationProperties.put("lazy-loading-enabled","true");
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setTypeAliasesPackage("com.sxkiler.demo.demo.test");
        bean.setTypeHandlersPackage("com.sxkiler.demo.demo.test");
        bean.setMapperLocations(ResourceUtils.getResources("classpath:mapper/*.xml"));
        factory = bean.getObject();
        SqlSession sqlSession = factory.openSession();
        MapperRegistry registry = factory.getConfiguration().getMapperRegistry();
        Field field = MapperRegistry.class.getDeclaredField("knownMappers");
        field.setAccessible(true);
        Map<Class<?>, MapperProxyFactory<?>> knownMappers = (Map<Class<?>, MapperProxyFactory<?>>)field.get(registry);
        Iterator<Map.Entry<Class<?>, MapperProxyFactory<?>>> it = knownMappers.entrySet().iterator();
        while(it.hasNext()){
            Map.Entry<Class<?>, MapperProxyFactory<?>> value = it.next();
            Class daoClass = value.getKey();
            MapperProxyFactory daoBean = value.getValue();
            Object obj = daoBean.newInstance(sqlSession);
            logger.info("加载dao对象,{}",daoClass.getSimpleName());
            BeanUtils.addBean(daoClass.getSimpleName(),obj);
        }
        logger.info("startup,mybatis,usetime,{}",System.currentTimeMillis()- starttime);
    }
    public static <T> T getDao(Class<T> daoBeanClass){
        return BeanUtils.getApplicationBean(daoBeanClass.getSimpleName());
    }

}
